package org.qrd.openmayyam;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import sun.awt.image.ByteInterleavedRaster;
import sun.misc.URLClassPath;

	/**
	 * A custom class loader that loads servlets on the fly
	 * @author Adarsh
	 * @author Sivaraman
	 */
public class CustomClassLoader extends ClassLoader {
	
	
	/**
	 * classPath contains the CLASSPATH system variable 
	 */
	private String classPath;
	
	/**
	 * main() method is used to test this class loader as a standalone application 
	 */
	
	public static void main(String[] args) {
		CustomClassLoader cl =  new CustomClassLoader();
		Class cls = cl.getClass("/home/adarsh/sample/WEB-INF/classes/mypackage/Hello.class", "mypackage.Hello");
		try {
			HttpServlet hs = (HttpServlet)cls.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * Returns the class requested for
	 * @param classPath The classPath system variable
	 * @param className The className is the complete class name the user requested for
	 */
	
	public Class getClass(String classPath, String className){
		this.classPath = classPath;
		return loadClass(className,true);
	}
	
	/**
	 * Returns the class bytes
	 */
	
	private byte[] getBytes() throws IOException {
		File f=new File(classPath);
		long len=f.length();
		byte raw[]=new byte[(int)len];
		FileInputStream fis=new FileInputStream(f);
		int r=fis.read(raw);
		if(r!=len)
			System.out.println("cant read");
		fis.close();
		return raw;
		
	}
	
	/**
	 * (non-Javadoc)
	 * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
	 * @param name The complete class name
	 * @param resolve boolean value indicating whether the class should be resolved
	 */
	
	 protected Class loadClass(String name, boolean resolve) {
		 System.out.println(name);
		Class clazz=null;
		try {
			// Load the class from the JVM
			clazz = CustomClassLoader.class.getClassLoader().loadClass(name);
			return clazz;
		} catch (ClassNotFoundException e) {
			System.out.println(name+" Not Found");
		}
		byte raw[]=null;
		try {
			// Get the raw bytes of the class
			raw = getBytes();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


		clazz=defineClass(name,raw, 0, raw.length);
		
		return clazz;
	}
	
}